package com.example.netty.client.tcp;

import org.springframework.util.ObjectUtils;

import java.net.InetAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class TcpClientCache {

    private static final Map<String, TcpClient> clientCache = new ConcurrentHashMap<>(128);

    private static final Object lock = new Object();


    public static TcpClient getClient(String ip, int port) throws Exception {
        String key = String.format("%s_%d", ip, port);
        boolean reachable = InetAddress.getByName(ip).isReachable(1000); //ping 判断网络是否通畅，以免短时间多次重连端口占用不可用
        if (reachable) {
            TcpClient tcpClient = clientCache.get(key);
            if (tcpClient != null) {
                if (tcpClient.isOpen()) {
                    return tcpClient;
                } else {
                    removeClient(ip, port);
                }
            }
            synchronized (lock) {
                if (!clientCache.containsKey(key)) {
                    tcpClient = new TcpClient(ip, port);
                    clientCache.put(key, tcpClient);
                } else {
                    tcpClient = clientCache.get(key);
                }
            }
            return tcpClient;
        } else {
            removeClient(ip, port);
            throw new Exception(String.format("(%s)网络异常！", ip));
        }
    }


    /**
     * 移除连接缓存
     *
     * @param ip
     * @param port
     */
    public static void removeClient(String ip, int port) {
        String key = String.format("%s_%d", ip, port);
        TcpClient tcpClient = clientCache.remove(key);
        if (!ObjectUtils.isEmpty(tcpClient)) {
            tcpClient.close();
        }
    }
}
